package com.avic.tools.utils;

import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.sl.extractor.SlideShowExtractor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFShape;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * FileParsing 解析pdf、doc、docx、ppt、xls等文件
 *
 * @author eomer
 * @date 22/5/6 14:31
 */
public class FileParsing {

    /**
     * 读取doc文件
     *
     * @param filePath
     * @throws Exception
     */
    public static String getTextFromDoc(String filePath) throws Exception {
        StringBuilder sb = new StringBuilder();
        FileInputStream fis = new FileInputStream(new File(filePath));
        HWPFDocument doc = new HWPFDocument(fis);
        Range rang = doc.getRange();
        sb.append(rang.text());
        fis.close();
        return sb.toString();

    }

    /**
     * 读取docx文件
     *
     * @param filePath
     * @throws IOException
     */
    public static String getTextFromDocx(String filePath) throws IOException {
        FileInputStream in = new FileInputStream(filePath);
        XWPFDocument doc = new XWPFDocument(in);
        XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
        String text = extractor.getText();
        in.close();
        return text;
    }

    /**
     * 读取pdf文件
     *
     * @param filePath
     * @throws IOException
     */
    public static String getTextFromPDF(String filePath) throws IOException {
        File input = new File(filePath);
        PDDocument pd = PDDocument.load(input);
        PDFTextStripper stripper = new PDFTextStripper();
        String content = stripper.getText(pd);
        pd.close();
        return content;
    }

    /**
     * 读取ppt文件
     *
     * @param filePath
     * @throws IOException
     */
    public static String getTextFromPPT(String filePath) throws IOException {
        XMLSlideShow slideshow = null;
        try {
            slideshow = new XMLSlideShow(new FileInputStream(new File(filePath)));
        } catch (IOException e) {
            e.printStackTrace();
        }
        SlideShowExtractor<XSLFShape, XSLFTextParagraph> slideShowExtractor
                = new SlideShowExtractor<>(slideshow);
        return slideShowExtractor.getText();
    }

    /**
     * 读取pptx文件
     *
     * @param filePath
     * @throws IOException
     */
    public static String getTextFromPPTX(String filePath) throws IOException {
        String resultString = null;
        StringBuilder sb = new StringBuilder();
        FileInputStream in = new FileInputStream(filePath);
        try {
            XMLSlideShow xmlSlideShow = new XMLSlideShow(in);
            List<XSLFSlide> slides = xmlSlideShow.getSlides();
            for (XSLFSlide slide : slides) {
                CTSlide rawSlide = slide.getXmlObject();
                CTGroupShape gs = rawSlide.getCSld().getSpTree();
                CTShape[] shapes = gs.getSpArray();
                for (CTShape shape : shapes) {
                    CTTextBody tb = shape.getTxBody();
                    if (null == tb) {
                        continue;
                    }
                    CTTextParagraph[] paras = tb.getPArray();
                    for (CTTextParagraph textParagraph : paras) {
                        CTRegularTextRun[] textRuns = textParagraph.getRArray();
                        for (CTRegularTextRun textRun : textRuns) {
                            sb.append(textRun.getT());
                        }
                    }
                }
            }
            resultString = sb.toString();
            xmlSlideShow.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultString;
    }

    /**
     * 读取xls xlsx
     *
     * @param filePath
     * @throws IOException
     */
    public static String getTextFromxls(String filePath) throws IOException {
        FileInputStream in = new FileInputStream(filePath);
        StringBuilder content = new StringBuilder();
        Workbook workbook;
        // 适配 2006 2007
        if (filePath.endsWith("xls")) {
            workbook = new HSSFWorkbook(in);
        } else {
            workbook = new XSSFWorkbook(in);
        }

        for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
            Sheet sheet = workbook.getSheetAt(sheetIndex);
            for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                Row row = sheet.getRow(rowIndex);
                if (row == null) {
                    continue;
                }
                for (int cellnum = 0; cellnum < row.getLastCellNum(); cellnum++) {
                    Cell cell = row.getCell(cellnum);
                    if (cell != null) {
                        if (cell.getCellType() != CellType.NUMERIC) {
                            content.append(cell.getRichStringCellValue().getString()).append(" ");
                        } else {
                            content.append(cell.getNumericCellValue()).append(" ");
                        }
                    }

                }
                content.append("\n");
            }

        }
        workbook.close();
        return content.toString();
    }

    /**
     * 解析csv文件并转成bean（方法二）
     *
     * @param file csv文件
     * @return 数组
     */
    public static List<String[]> getCsvDataMethod2(MultipartFile file, String encoding) {

        List<String[]> list = new ArrayList<String[]>();
        int i = 0;
        try {
            CSVReader csvReader = new CSVReaderBuilder(
                    new BufferedReader(
                            new InputStreamReader(file.getInputStream(), encoding))).build();
            Iterator<String[]> iterator = csvReader.iterator();
            while (iterator.hasNext()) {
                String[] next = iterator.next();
                //去除第一行的表头，从第二行开始
                if (i >= 1) {
                    list.add(next);
                }
                i++;
            }
            return list;
        } catch (Exception e) {
            System.out.println("CSV文件读取异常");
            return list;
        }
    }


    /**
     * 解析csv文件并转成bean（方法三）
     *
     * @param file  csv文件
     * @param clazz 类
     * @param <T>   泛型
     * @return 泛型bean集合
     */
    public static <T> List<T> getCsvDataMethod3(MultipartFile file, Class<T> clazz) {
        InputStreamReader in = null;
        CsvToBean<T> csvToBean = null;
        try {
            in = new InputStreamReader(file.getInputStream(), "utf-8");
            HeaderColumnNameMappingStrategy<T> strategy = new HeaderColumnNameMappingStrategy<>();
            strategy.setType(clazz);
            csvToBean = new CsvToBeanBuilder<T>(in).withMappingStrategy(strategy).build();
        } catch (Exception e) {
            return null;
        }
        return csvToBean.parse();
    }


    /**
     * 解析csv文件并转成bean（方法一）
     *
     * @return
     */
    /*public static List<CsvFile> getCsvDataMethod1(MultipartFile file) {
        ArrayList<CsvFile> csvFileList = new ArrayList<>();

        InputStreamReader in = null;
        String s = null;
        try {
            in = new InputStreamReader(file.getInputStream(), "utf-8");
            BufferedReader bufferedReader = new BufferedReader(in);
            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                String[] split = line.split(",");
                CsvFile csvFile = new CsvFile();
                csvFile.setName(splitResult(split[0]));
                csvFile.setTitle(splitResult(split[1]));
                csvFile.setNumber(splitResult(split[2]));
                csvFile.setType(splitResult(split[3]));
                csvFile.setPersonnel(splitResult(split[4]));
                csvFile.setTime(splitResult(split[5]));
                csvFileList.add(csvFile);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return csvFileList;
    }*/
    private static String splitResult(String once) {
        String result = "";
        for (int i = 0; i < once.length(); i++) {
            if (once.charAt(i) != '"') {
                result += once.charAt(i);
            }
        }
        return result;
    }

    /**
     * 读取TXT 文件
     *
     * @param filePath
     * @return java.util.List
     * @Date 22/5/6 16:45
     * @auther eomer
     */
    public static List getPremiumTxt(String filePath) {
        try {
            //接受传入的流 改为gbk编码
            FileInputStream in = new FileInputStream(filePath);
            BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
            //生成文件唯一编号
            String lineTxt;
            List<String> dataList = new ArrayList<>();
            while ((lineTxt = br.readLine()) != null) {
                dataList.add(lineTxt);
            }
            br.close();
            return dataList;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
